#include "stdafx.h"
#include "evdictbase.h"
#include "evdictstruct.h"
#include <conio.h>
#include <string.h>
#include <iostream>
using namespace std;

// cau truc bang bam
struct WordList* hashTable[26][7][7][7];
struct BackupWord * backupWord;

int RemovedRecord[1000];
// Ham ghi tu va dia chi tu vao bang bam
void addWordToHashTable(char* word, char* hashCode, int address)
{
	struct WordList *p;
	int x,y,z,t;
	x = *hashCode - 97;
	y = *(hashCode + 1) - 48;
	z = *(hashCode + 2) - 48;
	t = *(hashCode + 3) - 48;
	/*p = hashTable[*hashCode - 97][*(hashCode + 1) - 48][*(hashCode + 2) - 48][*(hashCode + 3) - 48];
	if(p == NULL)
	{
		p = new struct WordList;
		p->address = address;
		strcpy_s(p->word, word);
		p->next = NULL;
		hashTable[*hashCode - 97][*(hashCode + 1) - 48][*(hashCode + 2) - 48][*(hashCode + 3) - 48] = p;
	}
	else
	{
		while(p->next != NULL)
			p = p->next;
		struct WordList *t = new struct WordList;
		t->address = address;
		strcpy_s(t->word, word);
		t->next = NULL;
		p->next = t;
	}*/
	p = new struct WordList;
	p->address = address;
	strcpy(p->word,word);
	p->next = hashTable[x][y][z][t];
	hashTable[x][y][z][t] = p;
}

// Ham lay ve dia chi cua tu trong file Dictionary.dat dua vao ma bam
int getWordAddress(char* word, char* hashCode)
{
	struct WordList *p;
	p = hashTable[*hashCode - 97][*(hashCode + 1) - 48][*(hashCode + 2) - 48][*(hashCode + 3) - 48];
	if(p == NULL)
		return NOT_FOUND;
	else
	{
		while(p != NULL)
		{
			if(!strcmp(p->word, word))
				return p->address;
			p = p->next;
		}
		return NOT_FOUND;
	}
}

// Ham xoa 1 tu trong bang bam
void deleteWordFromHashTable( char* word, char* hashCode )
{
	struct WordList *p;
	int x,y,z,t;
	x = *hashCode - 97;
	y = *(hashCode + 1) - 48;
	z = *(hashCode + 2) - 48;
	t = *(hashCode + 3) - 48;
	p = hashTable[x][y][z][t];
	if(p == NULL) 
		return;
	if(!strcmp(p->word, word))
	{
		hashTable[x][y][z][t] = NULL;
		delete p;
	}
	else
	{
		while(strcmp(p->next->word, word))
			p = p->next;
		struct WordList *t = p->next->next;
		delete p->next;
		p->next = t;
	}
}

// ham ghi tu vao file Index
int writeWordToFile(WordIndex word, char* path)
{
	int rs;
	FILE *fp;	
	fp=fopen(path,"a+b");
	rs=ftell(fp);
	fwrite(&word,sizeof(struct WordIndex),1,fp);
	fclose(fp);
	return rs; 
}


//ham ghi tu vao file Definition

int writeWordToFile(WordDefinition word, char* path)
{
	int rs;
	FILE *fp;
	fp=fopen(path,"a+b");
	fseek(fp,0,SEEK_END);
	rs=ftell(fp);
	fwrite(&word,sizeof(struct WordDefinition),1,fp);
	fclose(fp);
	return rs;
	
}


//************************************
// Method:    writeWordToFile
// FullName:  writeWordToFile
// Access:    public 
// Returns:   int
// Qualifier:
// Parameter: WordDefinition word
// Parameter: char * path
// Parameter: int address
//************************************
void writeWordToFile(WordDefinition word, char* path, int address)
{
	int rs;
	FILE *fp;
	fp=fopen(path,"r+b");
	fseek(fp,address,SEEK_SET);
	fwrite(&word,sizeof(struct WordDefinition),1,fp);
	fclose(fp);
}


// ham ghi tu bi xoa vao file
int writeWordToFile(int address, char *path)
{
	int rs;
	FILE *fp;
	fp=fopen(path,"r+b");
	fseek(fp,address,SEEK_SET);
	rs=ftell(fp);
	fwrite(&address,sizeof(int),1,fp);
	fclose(fp);
	return rs;
}

boolean loadData(char * pathIndex,char * pathRemovedRecord)
{
	struct WordIndex wordIndex;
	struct WordList * word, * tempPointer;
	struct BackupWord * bw1;
	FILE *fIndex,*fRR;
	int x,y,z,t,tempInt;
	int removedAddress;
	
	fIndex = fopen(pathIndex,"a+b");
	fRR = fopen(pathRemovedRecord,"a+b");
	
	//load Index file
	int c;
	while((c = fread(&wordIndex,sizeof(struct WordIndex),1,fIndex)) && !feof(fIndex))
	{
		
		word = new struct WordList;
		word->address = wordIndex.address;
		strcpy(word->word,wordIndex.word);
		word->next = NULL;
		x = wordIndex.hashCode[0] - 97;
		y = wordIndex.hashCode[1] - 48;
		z = wordIndex.hashCode[2] - 48;
		t = wordIndex.hashCode[3] - 48;
	/*
			tempPointer = hashTable[x][y][z][t];
				if(tempPointer == NULL)
				{
					hashTable[x][y][z][t] = word;
				}
				else
				{
					while(tempPointer->next != NULL)
					{
						tempPointer = tempPointer->next;
					}
					tempPointer->next = word;
				}*/
		word->next = hashTable[x][y][z][t];
		hashTable[x][y][z][t] = word;
	}

	//load removed record File
	//bw1 = backupWord;
	while((c = fread(&tempInt,sizeof(int),1,fRR)) && !feof(fRR))
	{
		/*
		if(bw1 == NULL)
				{
					bw1 = new struct BackupWord;
					bw1->address = tempInt;
				}
				else
				{
					while(bw1->next != NULL)
					{
						bw1 = bw1->next;
					}
					bw1->next = new struct BackupWord;
					bw1->next->address = tempInt;
					bw1 = bw1->next;
				}*/
		bw1 = new struct BackupWord;
		bw1->next = backupWord;
		backupWord = bw1;
	}

	fclose(fIndex);
	fclose(fRR);
	return false;
}

WordDefinition getWordDefinitionByAddress(char* path, int address)
{
	FILE *f;
	WordDefinition wd;
	f = fopen(path,"rb");
	fseek(f,address,SEEK_SET);
	fread(&wd,sizeof(struct WordDefinition),1,f);
	fclose(f);
	return wd;
}

void addWordToBackUpList(int address)
{
	//add removed word 's address to backup list
	BackupWord * p = new BackupWord;
	p->address = address;
	p->next = backupWord;
	backupWord = p;

	//rewrite backup list to backup file
	updateBackupFile();
}

boolean isBackupListEmpty()
{
	if(backupWord == NULL)
		return TRUE;
	else
		return FALSE;
}

int getAvailableAddress()
{
	int address = backupWord->address;
	BackupWord *p = backupWord;
	backupWord = backupWord->next;
	delete p;
	updateBackupFile();
	return address;
}

void updateBackupFile()
{
	FILE *f;
	int temp;
	struct BackupWord *p;
	f = fopen(DICTIONARY_BACKUP_FILE,"wb");
	p = backupWord;
	while(p != NULL)
	{
		temp = p->address;
		fwrite(&temp,sizeof(int),1,f);
		p = p->next;
	}
	fclose(f);
}

//void updateIndexFile()
//{
//	FILE *f;
//	f = fopen(DICTIONARY_INDEX_FILE,"wb");
//	int i;
//	struct WordIndex wordIndex = new struct WordIndex;
//	struct WordList *p;
//	for(i = 0;i < 8918;i++)
//	{
//		if((p = hashTable + i) == NULL)
//			continue;
//		while(p!= NULL)
//		{
//			strcpy(wordIndex.word)
//		}
//	}
//}